﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace openssl_test
{
    internal class Program
    {
        //定义一个Dll import
        [DllImport("*")]
        internal static extern void SetIcsNativeaotActiveCode(byte[] activeCode);

        public static void AesTest()
        {
            // 明确指定 key/iv（仅用于测试）
            var key = new byte[16] { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
            var iv = new byte[16] { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF };
            var plaintext = new byte[16] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

            byte[] ciphertext;
            // 使用 TransformFinalBlock 生成完整密文
            using (var aes = System.Security.Cryptography.Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;
                using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
                {
                    ciphertext = encryptor.TransformFinalBlock(plaintext, 0, plaintext.Length);
                }
            }

            byte[] decryptedtext;
            // 使用 TransformFinalBlock 解密
            using (var aes = System.Security.Cryptography.Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;
                using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
                {
                    decryptedtext = decryptor.TransformFinalBlock(ciphertext, 0, ciphertext.Length);
                }
            }

            // 验证解密结果
            if (decryptedtext.Length != plaintext.Length)
            {
                throw new Exception($"AES Decryption failed: length mismatch ({decryptedtext.Length} vs {plaintext.Length})");
            }

            for (int i = 0; i < plaintext.Length; i++)
            {
                if (plaintext[i] != decryptedtext[i])
                {
                    throw new Exception("AES Decryption failed: content mismatch!");
                }
            }

            Debug.WriteLine("AES test succeeded!");
        }
        //测试Hash
        public static void HashTest()
        {
            var data = new byte[] { 1, 2, 3, 4, 5 };
            byte[] hash;
            using (var sha256 = System.Security.Cryptography.SHA256.Create())
            {
                hash = sha256.ComputeHash(data);
            }
            var pchashBytes = new byte[32]{ 0x74,0xF8,0x1F,0xE1,0x67,0xD9,0x9B,0x4C,0xB4,0x1D,0x6D,0x0C,0xCD,0xA8,0x22,0x78,0xCA,0xEE,0x9F,0x3E,0x2F,0x25,0xD5,0xE5,0xA3,0x93,0x6F,0xF3,0xDC,0xEC,0x60,0xD0,};

            for (int i = 0; i < hash.Length; i++)
            {
                if (hash[i] != pchashBytes[i])
                {
                    throw new Exception("Hash test failed!");
                }
            }
            //如果通过验证，打印成功信息
            Debug.WriteLine("Hash test succeeded!");

        }
        //测试RSA
        public static void RsaTest()
        {
            // 优先从当前工作目录读取私钥文件 rsa_private.pem（支持 PKCS#1 或 PKCS#8 格式）
            var cwd = Directory.GetCurrentDirectory()+"/key/rsa";
            var privPath = Path.Combine(cwd, "private_key.pem");
            if (!File.Exists(privPath))
            {
                throw new FileNotFoundException($"RSA 私钥文件未找到：{privPath}\n请把 PEM 格式私钥放到当前目录，文件名为 private_key.pem");
            }

            var pem = File.ReadAllText(privPath);

            // 导入私钥并执行签名/验签测试
            using (var rsa = System.Security.Cryptography.RSA.Create())
            {
                // ImportFromPem 接受 ReadOnlySpan<char>
                rsa.ImportFromPem(pem.AsSpan());

                var data = new byte[] { 1, 2, 3, 4, 5 };
                var signature = rsa.SignData(data, System.Security.Cryptography.HashAlgorithmName.SHA256, System.Security.Cryptography.RSASignaturePadding.Pkcs1);
                var isValid = rsa.VerifyData(data, signature, System.Security.Cryptography.HashAlgorithmName.SHA256, System.Security.Cryptography.RSASignaturePadding.Pkcs1);
                if (!isValid)
                {
                    throw new Exception("RSA Sign/Verify failed!");
                }
                else
                {
                    Debug.WriteLine("RSA Sign/Verify succeeded (imported key).");
                }
            }
        }
        public static void EccTest()
        {
            // 从当前工作目录读取 ECC 私钥，路径： <cwd>/key/ecc/ecc_private.pem
            var cwd = Directory.GetCurrentDirectory() + "/key/ecc";
            var privPath = Path.Combine(cwd, "ecc_private.pem");
            if (!File.Exists(privPath))
            {
                throw new FileNotFoundException($"ECC 私钥文件未找到：{privPath}\n请把 PEM 格式的 ECC 私钥放到该路径，文件名为 ecc_private.pem");
            }

            var pem = File.ReadAllText(privPath);

            // 导入私钥并做签名/验签测试
            using (var ecdsa = System.Security.Cryptography.ECDsa.Create())
            {
                // 支持的 PEM 格式示例：
                // -----BEGIN EC PRIVATE KEY-----  （SEC1）
                // -----BEGIN PRIVATE KEY-----     （PKCS#8）
                ecdsa.ImportFromPem(pem.AsSpan());

                var data = new byte[] { 1, 2, 3, 4, 5 };
                var signature = ecdsa.SignData(data, System.Security.Cryptography.HashAlgorithmName.SHA256);
                var isValid = ecdsa.VerifyData(data, signature, System.Security.Cryptography.HashAlgorithmName.SHA256);
                if (!isValid)
                {
                    throw new Exception("ECC Sign/Verify failed!");
                }
                else
                {
                    Debug.WriteLine("ECC Sign/Verify succeeded (imported key).");
                }
            }
        }

        static void Main(string[] args)
        {
            var activeCode = new byte[] { 0x3B, 0xD9, 0xDD, 0xF5, 0x00, 0xCE, 0x42, 0x8D, 0x5D, 0xAA, 0xEA, 0x90, 0x81, 0xB8, 0xEE, 0x80, 0xAB, 0xCD, 0x78, 0x71, 0xA3, 0xB1, 0x97, 0x4F, 0x9C, 0x01, 0xCE, 0xE2, 0x58, 0x0A, 0x84, 0xB1, };
            //获取当前platform
            var platform = RuntimeInformation.ProcessArchitecture;
            if (platform == Architecture.Arm)
            {
                SetIcsNativeaotActiveCode(activeCode);
                Directory.SetCurrentDirectory("/mnt/sd0/home");
                Debug.WriteLine("当前是嵌入式平台,如果你要跑这个例子,请将key目录下的所有东西复制到SD卡中的home目录!因为rsa 和ecc需要导入key文件");
            }

            AesTest();
            HashTest();
            RsaTest();
            EccTest();
            Debug.WriteLine("Hello, World!");
        }
    }
}
